#pragma once

#include <linux/rcupdate.h>

struct task_struct;
struct pid;

struct kernel_clone_args
{
	int (*fn)(void *);
	void *fn_arg;
	const char *name;
	u64 flags;
	unsigned int kthread : 1;
	unsigned int idle : 1;
	int exit_signal;
};

extern struct task_struct init_task;

extern void init_idle(struct task_struct *idle, int cpu);

extern int sched_fork(unsigned long clone_flags, struct task_struct *p);
extern int copy_thread(struct task_struct *, const struct kernel_clone_args *);

void schedule_tail(struct task_struct *prev);

void put_task_struct(struct task_struct *t);
struct task_struct *get_task_struct(struct task_struct *p);
void put_task_stack(struct task_struct *tsk);
extern void free_task(struct task_struct *tsk);
int fork_idle(int cpu, struct task_struct **tsk_ret);

int copy_process(struct pid *pid, int trace, int node,
                   struct kernel_clone_args *args, struct task_struct **tsk);
struct task_struct *get_task_struct(struct task_struct *t);

void __noreturn sched_task_dead(void);
void put_task_finish_switch(struct task_struct *task);

extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags);
extern pid_t kernel_thread(int (*fn)(void *), void *arg, const char *name,
						   unsigned long flags);
extern pid_t kernel_clone(struct kernel_clone_args *kargs);
